package com.qqt.csr.order.service.event;

import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import com.qqt.csr.common.session.SessionContextHolder;
import com.qqt.csr.order.entity.OrderDynamic;
import com.qqt.csr.order.enums.DynamicType;
import com.qqt.csr.order.enums.WorkOrderEventEnum;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationEvent;

import java.io.Serial;
import java.util.Collections;
import java.util.List;

import static com.qqt.csr.order.service.event.DynamicTemplate.*;

/**
 * @Author: yang hao
 * @Date: 2024/12/13 16:58
 * @Description: 动态事件
 **/
public class DynamicEvent extends ApplicationEvent {

    @Serial
    private static final long serialVersionUID = 2150493605350686232L;

    /**
     * Create a new {@code DynamicEvent}.
     *
     * @param source {@link DynamicEventSource} 动态源
     */
    public DynamicEvent(DynamicEventSource source) {
        super(source);
    }

    /**
     * 获取动态列表
     *
     * @return {@link List<OrderDynamic>} 动态列表
     */
    public List<OrderDynamic> orderDynamics() {
        DynamicEventSource source;
        if (this.source instanceof DynamicEventSource) {
            source = (DynamicEventSource) this.source;
        } else {
            return Collections.emptyList();
        }
        WorkOrderEventEnum event = source.getEvent();
        return switch (event) {
            case CREATED -> generateDynamics(source, CREATE_TEMPLATE);
            case CREATED_ALLOCATED -> generateDynamics(source, CREATE_TEMPLATE, RECEIVED_TEMPLATE);
            case ALLOCATED -> allocatedDynamics(source);
            case RECEIVED -> generateDynamics(source, RECEIVED_TEMPLATE);
            case SUSPENDED -> generateDynamics(source, SUSPENDED_TEMPLATE);
            case RECOVERED -> generateDynamics(source, RECOVERED_TEMPLATE);
            case REOPENED -> generateDynamics(source, REOPENED_TEMPLATE);
            case COMPLETED -> generateDynamics(source, COMPLETED_TEMPLATE);
            case UPDATED_DESIGNEE -> updatedDesigneeDynamics(source);
            case EDITED, EDIT_ALLOCATED -> editedDynamics(source);
            case DELETED -> generateDynamics(source, DELETED_TEMPLATE);
        };
    }

    /**
     * 通用动态生成
     *
     * @param source    {@link DynamicEventSource} 动态事件数据源
     * @param templates {@link String}[] 动态模板集合
     * @return {@link List<OrderDynamic>} 动态列表
     */
    private List<OrderDynamic> generateDynamics(DynamicEventSource source, String... templates) {
        if (templates == null) {
            return Collections.emptyList();
        }
        // 获取参数
        String currentUsername = SessionContextHolder.getHeaderInfo().getNickName();
        Object[] params = new Object[]{currentUsername};
        // 创建动态
        List<OrderDynamic> dynamics = Lists.newArrayList();
        for (String template : templates) {
            OrderDynamic dynamic = dynamic(template, params, source);
            dynamics.add(dynamic);
        }
        return dynamics;
    }

    /**
     * 分配事件动态
     *
     * @param source {@link DynamicEventSource} 动态事件数据源
     * @return {@link List<OrderDynamic>} 动态列表
     */
    private List<OrderDynamic> allocatedDynamics(DynamicEventSource source) {
        // 获取参数
        String currentUsername = SessionContextHolder.getHeaderInfo().getNickName();
        OrderDynamic dynamic;
        // 创建动态
        if (StrUtil.isBlank(source.getReasonForAssignment())) {
            Object[] params = new Object[]{currentUsername, source.getProcessor()};
            dynamic = dynamic(ALLOCATED_NO_REASON_TEMPLATE, params, source);
        } else {
            Object[] params = new Object[]{currentUsername, source.getProcessor(), source.getReasonForAssignment()};
            dynamic = dynamic(ALLOCATED_TEMPLATE, params, source);
        }
        return Lists.newArrayList(dynamic);
    }

    /**
     * 变更处理人事件动态
     *
     * @param source {@link DynamicEventSource} 动态事件数据源
     * @return {@link List<OrderDynamic>} 动态列表
     */
    @SuppressWarnings("all")
    private List<OrderDynamic> updatedDesigneeDynamics(DynamicEventSource source) {
        // 获取参数
        String currentUsername = SessionContextHolder.getHeaderInfo().getNickName();
        OrderDynamic dynamic;
        // 创建动态
        if (StrUtil.isBlank(source.getReasonForAssignment())) {
            Object[] params = new Object[]{currentUsername, source.getProcessor()};
            dynamic = dynamic(UPDATED_DESIGNEE_NO_REASON_TEMPLATE, params, source);
        } else {
            Object[] params = new Object[]{currentUsername, source.getProcessor(), source.getReasonForAssignment()};
            dynamic = dynamic(UPDATED_DESIGNEE_TEMPLATE, params, source);
        }
        return Lists.newArrayList(dynamic);
    }

    /**
     * 编辑事件动态
     *
     * @param source {@link DynamicEventSource} 动态事件数据源
     * @return {@link List<OrderDynamic>} 动态列表
     */
    private List<OrderDynamic> editedDynamics(DynamicEventSource source) {
        // 获取参数
        String currentUsername = SessionContextHolder.getHeaderInfo().getNickName();
        Object[] params = new Object[]{currentUsername};
        // 创建动态
        String template = EDITED_TEMPLATE;
        if (source.getChangeFields() != null) {
            StringBuilder sb = new StringBuilder();
            for (DynamicEventSource.ChangeField changeField : source.getChangeFields()) {
                sb.append("修改").append(changeField.getField());
                if (StringUtils.isNotBlank(changeField.getNewValue())) {
                    sb.append("为").append(changeField.getNewValue());
                }
                sb.append(";");
            }
            template = EDITED_TEMPLATE + "," + sb;
        }
        OrderDynamic dynamic = dynamic(template, params, source);
        return Lists.newArrayList(dynamic);
    }

    /**
     * 创建动态
     *
     * @param template {@link String} 动态模板
     * @param params   {@link Object}[] 动态参数
     * @param source   {@link DynamicEventSource} 动态事件数据源
     * @return {@link OrderDynamic} 动态
     */
    private OrderDynamic dynamic(String template, Object[] params, DynamicEventSource source) {
        return OrderDynamic.builder()
                .type(DynamicType.ORDER_CHANGES.getValue())
                .creatorId(SessionContextHolder.getHeaderInfo().getUserId())
                .content(String.format(template, params))
                .orderId(source.getOrderId())
                .ext(source.getExt())
                .build();
    }

}
